案例(巧克力生产)

假设一家巧克力生产公司只生产两种类型的巧克力——A和B。这两种巧克力只需要牛奶和巧克力。制造A和B的每一个单位,需要以下数量:

  • 每单位A需要1单位牛奶和3单位巧克力
  • 每单位B需要1单位牛奶和2单位巧克力

公司厨房里有5个单位的牛奶和12个单位的巧克力。每卖出一笔,公司就赚一笔

  • 每单位A卖出6卢比
  • 每单位B卖出5卢比

现在,该公司希望实现利润最大化。它应该分别生产多少单位的A和B ?

决策变量

目标函数

公司的总利润是A和B生产的总单位数乘以单位利润分别为6卢比和5卢比。
目标函数为 $$\max \quad Z = 6X+5Y$$

约束条件

$$ s.t. \begin{cases} X + Y \le 5 \\ 3 X + 2 Y \le 12 \\ X,Y \ge 0 \\ X,Y \in \mathbb{Z} \end{cases} $$

PuLP 库求解过程

PuLP是一个开源的第三方工具包,可以求解线性规划、整数规划、混合整数等规划问题。 借助上述案例求解我们介绍PuLP库的使用。在此之前我们需要先安装该库: 我们可以通过在命令行提示符cmd(对于Windows系统)或者终端Terminal(对于Mac系统)使用下述命令安装PuLP:

pip install pulp

一般我们在使用时将其简写为lp

import pulp as lp

或者嫌每次都输入lp麻烦的话,可以一次性导入该库的所有函数

from pulp import *

本文选用第一种导入方式

第一步:初始化模型

import pulp as lp # 引入库
model = lp.LpProblem(name='cho',sense=lp.LpMaximize) # 定义模型名字及模型是最大化还是最小化目标函数

通过lp.LpProblem定义模型,其参数设置为:

第二步:定义决策变量

x = lp.LpVariable('A',lowBound=0,upBound=4,cat='Integer') # 定义变量x,代表A的数量,最小值为0,最大值为4,变量为整数
y = lp.LpVariable('B',lowBound=0,upBound=5,cat='Integer') # 定义变量y,代表B的数量,最小值为0,最大值为5,变量为整数

lp.LpVariable定义决策变量,其参数设置为:

第三步:定义目标函数

objective = 6*x+5*y # 定义目标函数
model += objective, 'Maximize_Profit' # 将目标函数添加到模型中,并定义目标函数的名字为  'Maximize_Profit'

添加目标函数使用 “问题名 += 目标函数式” 格式。

第四步:定义约束条件

model += x+y<=5,'milk_constraint' # 定义约束条件,该条约束条件名称定义为 'milk_constraint'
model += 3*x+2*y<=12,'cho_constraint' # 定义约束条件,该条约束名称定义为 'cho_constraint'

添加约束条件使用 “问题名 += 约束条件表达式” 格式。约束条件可以是等式约束或不等式约束,不等式约束可以是 小于等于大于等于,分别使用关键字>=<=,等式约束使用==

第五步:求解

model.solve()

solve() 是求解函数。PuLP默认采用 CBC 求解器来求解优化问题,也可以调用其它的优化器来求解,如:GLPK,COIN CLP/CBC,CPLEX,和GUROBI,但需要另外安装。

model.solve()结果输出为1表明求解成功。

第六步:查看求解结果

打印模型

print(model)

结果为:

cho:
MAXIMIZE
6*A + 5*B + 0
VARIABLES
0 <= A <= 4 Integer
0 <= B <= 5 Integer

查看目标函数值和变量值

print('目标函数值:',lp.value(model.objective))
print('变量值 x:',lp.value(x))
print('变量值 y:',lp.value(y))

通过value函数可以查看模型目标函数和变量的取值。

目标函数值: 49.0
变量值 x: 4.0
变量值 y: 5.0

完整代码

print('目标函数值:',lp.value(model.objective))
print('变量值 x:',lp.value(x))
print('变量值 y:',lp.value(y))

通过value函数可以查看模型目标函数和变量的取值。

import pulp as lp
model = lp.LpProblem(name='cho',sense=lp.LpMaximize)
x = lp.LpVariable('A',lowBound=0,upBound=4,cat='Integer') # 定义变量x,代表A的数量,最小值为0,最大值为4,变量为整数
y = lp.LpVariable('B',lowBound=0,upBound=5,cat='Integer') # 定义变量y,代表B的数量,最小值为0,最大值为5,变量为整数
objective = 6*x+5*y # 定义目标函数
model += objective, 'Maximize_Profit' # 将目标函数添加到模型中,并定义目标函数的名字为  'Maximize_Profit'
model.solve()
print(model)
print('目标函数值:',lp.value(model.objective))
print('变量值 x:',lp.value(x))
print('变量值 y:',lp.value(y))

参考资料